package com.divemotor.ventarepuestosinternet.dao.impl;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.divemotor.ventarepuestosinternet.dao.TipoComponenteDAO;
import com.divemotor.ventarepuestosinternet.model.ModeloFabrica;
import com.divemotor.ventarepuestosinternet.model.TipoComponente;
import com.divemotor.ventarepuestosinternet.model.Vehiculo;
import com.divemotor.ventarepuestosinternet.model.VehiculoExtra;
import com.divemotor.ventarepuestosinternet.util.Constantes;

@SuppressWarnings("unchecked")
@Repository(value = "tipoComponenteDAO")
public class TipoComponenteDAOImpl implements TipoComponenteDAO, Serializable {

	private static final long serialVersionUID = 6407043770776437795L;
	
	@Autowired
	private SessionFactory sessionFactory;
	
	@Override
	public List<TipoComponente> listarActivos() {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(TipoComponente.class)
				.add(Restrictions.eq("estado", Constantes.ESTADO_ACTIVO))
				.addOrder(Order.asc("nombre"));
		return criteria.list();
	}

	@Override
	public TipoComponente obtenerPorId(TipoComponente tipoComponente) {
		return (TipoComponente) sessionFactory.getCurrentSession().get(TipoComponente.class, tipoComponente.getIdTipoComponente());
	}

	@Override
	public List<TipoComponente> listarTipoComponentesPorVehiculo(Vehiculo vehiculo) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ModeloFabrica.class, "modeloFabrica")
				.createAlias("modeloFabrica.listaVehiculoModeloFabrica", "vehiculoModeloFabrica")
				.createAlias("modeloFabrica.tipoComponente", "tipoComponente")
				.createAlias("vehiculoModeloFabrica.vehiculo", "vehiculo")
				.setProjection(Projections.projectionList().add(Projections.distinct(Projections.property("tipoComponente.idTipoComponente"))))
				.add(Restrictions.eq("vehiculo.chasis", vehiculo.getChasis()));
		
		List<Integer> listaIdsTipoComponentes = criteria.list();
		
		return listarTipoComponentesPorIds(listaIdsTipoComponentes);
	}

	@Override
	public List<TipoComponente> listarTipoComponentesPorVehiculoExtra(VehiculoExtra vehiculoExtra) {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(ModeloFabrica.class, "modeloFabrica")
				.createAlias("modeloFabrica.listaModelo", "modelo")
				.createAlias("modeloFabrica.tipoComponente", "tipoComponente")
				.createAlias("modelo.listaVehiculoExtra", "vehiculoExtra")
				.setProjection(Projections.projectionList().add(Projections.distinct(Projections.property("tipoComponente.idTipoComponente"))))
				.add(Restrictions.eq("vehiculoExtra.idVehiculoExtra", vehiculoExtra.getIdVehiculoExtra()));
		
		List<Integer> listaIdsTipoComponentes = criteria.list();
		
		return listarTipoComponentesPorIds(listaIdsTipoComponentes);
	}

	@Override
	public List<TipoComponente> listarTipoComponentesPorIds(List<Integer> listaIdsTipoComponentes) {
		if (listaIdsTipoComponentes != null && listaIdsTipoComponentes.size() > 0) {
			Criteria criteria = sessionFactory.getCurrentSession().createCriteria(TipoComponente.class, "tipoComponente")
					.add(Restrictions.in("tipoComponente.idTipoComponente", listaIdsTipoComponentes))
					.addOrder(Order.asc("tipoComponente.nombre"));
			return criteria.list();
		} else {
			return null;
		}
	}

}
